#include <bits/stdc++.h>
using namespace std;
/* 
func modify(arr, op, idx) {
    // add by 1 index idx
    if (op == 0) {
        arr[idx] = arr[idx] + 1
    }
    // multiply by 2 all elements
    if (op == 1) {
        for (i = 0; i < arr.length; i++) {
            arr[i] = arr[i] * 2
        }
    }
}

题目描述
给你一个与 nums 大小相同且初始值全为 0 的数组 arr，请你调用以上函数得到整数数组 nums。
请你返回将 arr 变成 nums 的最少函数调用次数。
答案保证在 32 位有符号整数以内。


示例 1：

输入：nums = [1,5]
输出：5
解释：给第二个数加 1 ：[0, 0] 变成 [0, 1] （1 次操作）。
将所有数字乘以 2 ：[0, 1] -> [0, 2] -> [0, 4] （2 次操作）。
给两个数字都加 1 ：[0, 4] -> [1, 4] -> [1, 5] （2 次操作）。
总操作次数为：1 + 2 + 2 = 5 。
示例 2：

输入：nums = [2,2]
输出：3
解释：给两个数字都加 1 ：[0, 0] -> [0, 1] -> [1, 1] （2 次操作）。
将所有数字乘以 2 ： [1, 1] -> [2, 2] （1 次操作）。
总操作次数为： 2 + 1 = 3 。
示例 3：

输入：nums = [4,2,5]
输出：6
解释：（初始）[0,0,0] -> [1,0,0] -> [1,0,1] -> [2,0,2] -> [2,1,2] -> [4,2,4] -> [4,2,5] （nums 数组）。
示例 4：

输入：nums = [3,2,2,4]
输出：7
示例 5：

输入：nums = [2,4,8,16]
输出：8
 

提示：

1 <= nums.length <= 10^5
0 <= nums[i] <= 10^9
*/

// 法一
class Solution {
public:
    int minOperations(vector<int>& nums) {
        // 处理全零的情况
        bool allZero = true;
        for (int num : nums) {
            if (num != 0) {
                allZero = false;
                break;
            }
        }
        if (allZero) return 0;

        int res = 0;
        int maxBit = 0;
        for (int num : nums) {
            int cnt = 0;
            int bit = 0;
            while (num > 0) {
                if (num & 1) {
                    cnt++;
                }
                num >>= 1;
                bit++;
            }
            res += cnt;
            if (bit > maxBit) {
                maxBit = bit;
            }
        }
        res += maxBit - 1;
        return res;
    }
};

// 法二
class Solution {
public:
    int minOperations(vector<int>& nums) {
        int ans=0,maxn=0;
        for(int i=0;i<nums.size();i++){
            ans+=__builtin_popcount(nums[i]);
            maxn=max(maxn,nums[i]);
        }
        int cnt=0;
        while(maxn){
            maxn>>=1;
            cnt++;
        }
        cnt--;
        return ans+max(cnt,0);
    }
};